﻿#include "PhysicsDialogRibbed.h"
#include "ui_PhysicsDialogRibbed.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyRibbed.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyRibInfo.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include <QMessageBox>
#include <QRegExp>
namespace GUI
{
    PhysicsDialogRibbed::PhysicsDialogRibbed(PhysicsDlgExecType type, int propid/*=-1*/, QWidget* parent /*= nullptr*/)
        :AbstractMaterialDialog(type, parent)
    {
        _ui = new Ui::PhysicsDialogRibbed;
        _ui->setupUi(this);
    //初始化均质板自由阻尼板下拉列表
        if (!_propMgr)return;
        QList<Acoustics::FITKAcousticsAbsPhysicsProp*> list = _propMgr->getPhysicsProps(Acoustics::FITKAcousticsAbsPhysicsProp::APPUniformPlat);
        list+= _propMgr->getPhysicsProps(Acoustics::FITKAcousticsAbsPhysicsProp::APPGeneralLaminatePhysicalProperty);
        if (!list.isEmpty()) {
            for (auto mate : list) {
                _ui->comboBox_uniform->addItem(mate->getDataObjectName(), mate->getDataObjectID());
            }
        }
    // 初始化筋的梁下拉列表
        QList<Acoustics::FITKAcousticsAbsPhysicsProp*> listBeam = _propMgr->getPhysicsProps(Acoustics::FITKAcousticsAbsPhysicsProp::APPBeam);
        if (!listBeam.isEmpty()) {
            for (auto mate : listBeam) {
                _ui->comboBox_R1_beam->addItem(mate->getDataObjectName(), mate->getDataObjectID());
                _ui->comboBox_R2_beam->addItem(mate->getDataObjectName(), mate->getDataObjectID());
            }
        }
        _ui->comboBox_R2_beam->setCurrentIndex(1);//0为None
    //初始化筋方向默认图片
        _ui->label_R1->setPixmap(QPixmap(":/browserIcons/ribbed_dir01_0.png"));
        _ui->label_R2->setPixmap(QPixmap(":/browserIcons/ribbed_dir02_0.png"));
    //获取材料对象
        if (propid > 0)
            _prop = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_propMgr->getDataByID(propid));

        this->init();

    }

    PhysicsDialogRibbed::~PhysicsDialogRibbed()
    {
        if (_ui) delete _ui;
    }

    void PhysicsDialogRibbed::on_pushButtonOK_clicked()
    {
        if (!this->checkInput()) return;
        //要处理的对象
        Acoustics::FITKPhyscisPropertyRibbed* ribbed = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_prop);
        //保存执行的脚本
        QStringList str;
        QString name = _ui->lineEdit_name->text();
        //创建与复制,创建新对象
        if (_execType == GUI::PhysicsDlgExecType::Create || _execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            str.append("p=PhyscisProp.Uniform()");
            str.append(QString("p.createPhyscisProp('%1')").arg(name));

            ribbed = new Acoustics::FITKPhyscisPropertyRibbed;
            _propMgr->appendDataObj(ribbed);
        }
        if (!ribbed)return;

        if (_execType == GUI::PhysicsDlgExecType::Edit)
        {
            str.append(QString("p=PhyscisProp.Ribbed.GetRibbed('%1')").arg(ribbed->getDataObjectName()));
            str.append(QString("p.setName('%1')").arg(name));
        }

        //保存数据  
        QString skinName = _ui->comboBox_uniform->currentText();
        double angle = _ui->lineEdit_baseAngle->text().toDouble();
        double r1offset = _ui->lineEdit_R1_offset->text().toDouble();
        double r1spacing = _ui->lineEdit_R1_spacing->text().toDouble();
        double r1Dev = _ui->lineEdit_R1_spacingDevFraction->text().toDouble() / 100;
        double r2offset = _ui->lineEdit_R2_offset->text().toDouble();
        double r2spacing = _ui->lineEdit_R2_spacing->text().toDouble();
        double r2Dev = _ui->lineEdit_R2_spacingDevFraction->text().toDouble() / 100;
        QString r1BeamName = _ui->comboBox_R1_beam->currentText();
        QString text1 = _ui->pushButton_R1->text();
        QRegExp re1("\\d+");
        re1.indexIn(text1, 2);//从第二个字符开始匹配
        double num1 = re1.cap(0).toDouble();
        QString r2BeamName = _ui->comboBox_R2_beam->currentText();
        QString text2 = _ui->pushButton_R2->text();
        QRegExp re2("\\d+");
        re2.indexIn(text2, 2);//从第二个字符开始匹配
        double num2 = re2.cap(0).toDouble();

        str.append(QString("p.setBaseAngle(%1)").arg(angle));
        str.append(QString("p.setSkinSection('%1')").arg(skinName));
        str.append(QString("p.setRibs_1('%1',%2,%3,%4,%5)").arg(r1BeamName).arg(r1spacing).arg(r1Dev).arg(r1offset).arg(num1));
        if(_propMgr->getDataByName(r2BeamName))
            str.append(QString("p.setRibs_2('%1',%2,%3,%4,%5)").arg(r2BeamName).arg(r2spacing).arg(r2Dev).arg(r2offset).arg(num2));
        else            
            str.append(QString("p.disableRibs_2()"));

        ribbed->setDataObjectName(name);
        ribbed->setSkinPropID(_ui->comboBox_uniform->currentData().toInt());
        ribbed->setBaseAngle(angle);

        Acoustics::FITKPhyscisPropertyRibInfo* r1 = ribbed->getDri1RibInfo();
        if (!r1)return;
        r1->setOffset(r1offset);
        r1->setSpacing(r1spacing);
        r1->setSpacingDevFraction(r1Dev);
        r1->setBeamPropID(_ui->comboBox_R1_beam->currentData().toInt());      
        r1->setOrientation(num1);

        Acoustics::FITKPhyscisPropertyRibInfo* r2 = ribbed->getDri2RibInfo();
        if (!r2)return;
        r2->setOffset(_ui->lineEdit_R2_offset->text().toDouble());
        r2->setSpacing(_ui->lineEdit_R2_spacing->text().toDouble());
        r2->setSpacingDevFraction(_ui->lineEdit_R2_spacingDevFraction->text().toDouble() / 100);
        auto beam2 = _propMgr->getDataByName(_ui->comboBox_R2_beam->currentText());
        if (beam2)
            r2->setBeamPropID(beam2->getDataObjectID());
        else
            r2->setBeamPropID(-1);
        r2->setOrientation(num2);

        this->saveScript(str);
        this->accept();
    }

    void PhysicsDialogRibbed::on_pushButtonCancel_clicked()
    {
        this->reject();
    }

    void PhysicsDialogRibbed::on_comboBox_R2_beam_currentTextChanged(QString text)
    {
        if (text == "None")
        {
            _ui->lineEdit_R2_spacing->setEnabled(false);
            _ui->lineEdit_R2_spacingDevFraction->setEnabled(false);
            _ui->lineEdit_R2_offset->setEnabled(false);
            _ui->pushButton_R2->setEnabled(false);
        }
        else
        {
            _ui->lineEdit_R2_spacing->setEnabled(true);
            _ui->lineEdit_R2_spacingDevFraction->setEnabled(true);
            _ui->lineEdit_R2_offset->setEnabled(true);
            _ui->pushButton_R2->setEnabled(true);
        }
    }

    void PhysicsDialogRibbed::on_pushButton_R1_clicked()
    {
        QString text=_ui->pushButton_R1->text();
        QRegExp re("\\d+");
        re.indexIn(text, 2);//从第二个字符开始匹配
        QString num = re.cap(0);
        int angle = num.toInt() + 90;
        if (angle == 360)angle = 0;
        QString path = ":/browserIcons/ribbed_dir01_" + QString::number(angle) + ".png";
        _ui->label_R1->setPixmap(QPixmap(path));
        _ui->pushButton_R1->setText(QString("1-Dir,Rib - %1 deg").arg(angle));
    }

    void PhysicsDialogRibbed::on_pushButton_R2_clicked()
    {
        QString text = _ui->pushButton_R2->text();
        QRegExp re("\\d+");
        re.indexIn(text, 2);//从第二个字符开始匹配
        QString num = re.cap(0);
        int angle = num.toInt() + 90;
        if (angle == 360)angle = 0;
        QString path = ":/browserIcons/ribbed_dir02_" + QString::number(angle) + ".png";
        _ui->label_R2->setPixmap(QPixmap(path));
        _ui->pushButton_R2->setText(QString("2-Dir,Rib - %1 deg").arg(angle));
    }

    void PhysicsDialogRibbed::init()
    {
        if (_propMgr == nullptr || _matMgr == nullptr) return;

        if (_execType == GUI::PhysicsDlgExecType::Create)
        {
            QString name = _propMgr->checkName("New Physics Property Ribbed");
            _ui->lineEdit_name->setText(name);
        }
        if (_prop == nullptr) return;
        Acoustics::FITKPhyscisPropertyRibbed* ribbed = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(_prop);
        if (!ribbed) return;

        // 设置各个属性的值
        _ui->lineEdit_name->setText(ribbed->getDataObjectName());
        Acoustics::FITKAcousticsAbsPhysicsProp* skinPhyProp = ribbed->getSkinPropObj();
        if (skinPhyProp) {
            int id1 = skinPhyProp->getDataObjectID();
            int index1 = _ui->comboBox_uniform->findData(id1);
            _ui->comboBox_uniform->setCurrentIndex(index1);
        }
        _ui->lineEdit_baseAngle->setText(QString::number(ribbed->getBaseAngle()));

        Acoustics::FITKPhyscisPropertyRibInfo* r1=ribbed->getDri1RibInfo();
        if (!r1)return;
        _ui->lineEdit_R1_spacing->setText(QString::number(r1->getSpacing()));
        _ui->lineEdit_R1_spacingDevFraction->setText(QString::number(r1->getSpacingDevFraction() * 100));
        _ui->lineEdit_R1_offset->setText(QString::number(r1->getOffset()));
        int angle1 = determineDirection(r1->getOrientation());
        QString path1 = ":/browserIcons/ribbed_dir01_" + QString::number(angle1) + ".png";
        _ui->label_R1->setPixmap(QPixmap(path1));
        _ui->pushButton_R1->setText(QString("1-Dir,Rib - %1 deg").arg(angle1));
        Acoustics::FITKAcousticsAbsPhysicsProp* beamPhyProp = r1->getBeamPropObj();
        if (beamPhyProp) {
            int id1 = beamPhyProp->getDataObjectID();
            int index1 = _ui->comboBox_R1_beam->findData(id1);
            _ui->comboBox_R1_beam->setCurrentIndex(index1);
        }
        Acoustics::FITKPhyscisPropertyRibInfo* r2 = ribbed->getDri2RibInfo();
        if (!r2)return;
        _ui->lineEdit_R2_spacing->setText(QString::number(r2->getSpacing()));
        _ui->lineEdit_R2_spacingDevFraction->setText(QString::number(r2->getSpacingDevFraction() * 100));
        _ui->lineEdit_R2_offset->setText(QString::number(r2->getOffset()));
        int angle2 = determineDirection(r2->getOrientation());
        QString path2 = ":/browserIcons/ribbed_dir02_" + QString::number(angle2) + ".png";
        _ui->label_R2->setPixmap(QPixmap(path2));
        _ui->pushButton_R2->setText(QString("2-Dir,Rib - %1 deg").arg(angle2));
        Acoustics::FITKAcousticsAbsPhysicsProp* beamPhyProp2 = r2->getBeamPropObj();
        if (beamPhyProp2) {
            int id2 = beamPhyProp2->getDataObjectID();
            int index2 = _ui->comboBox_R2_beam->findData(id2);
            _ui->comboBox_R2_beam->setCurrentIndex(index2);
        }else {
            _ui->comboBox_R2_beam->setCurrentIndex(0);
            _ui->lineEdit_R2_spacing->setEnabled(false);
            _ui->lineEdit_R2_spacingDevFraction->setEnabled(false);
            _ui->lineEdit_R2_offset->setEnabled(false);
            _ui->pushButton_R2->setEnabled(false);
        }

        //复制,更新名称
        if (_execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            QString text = QString("Copy of %1").arg(ribbed->getDataObjectName());
            _ui->lineEdit_name->setText(text);
        }
    }

    bool PhysicsDialogRibbed::checkInput()
    {
        //检查数据合法性
        QList<QLineEdit*> checkUi;
        checkUi << _ui->lineEdit_R2_spacing << _ui->lineEdit_R2_spacingDevFraction << _ui->lineEdit_R2_offset
            << _ui->lineEdit_R1_spacing << _ui->lineEdit_R1_spacingDevFraction << _ui->lineEdit_R1_offset<< _ui->lineEdit_baseAngle;
        for (QLineEdit* e : checkUi)
        {
            if (e == nullptr) continue;
            QString text = e->text().trimmed();
            bool ok = false;
            text.toDouble(&ok);
            if (!ok)
            {
                QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a number."));
                return false;
            }
        }
        if (_propMgr == nullptr) return false;
        //检查名称
        QString text = _ui->lineEdit_name->text().trimmed();
        if (text != "") {
            QString newText = _propMgr->checkName(text);
            if (text == newText) return true;
            //与自己重名
            if (_propMgr->getDataByName(text) == _prop) return true;
        }
        QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a new Name."));
        return false;
    }

    int PhysicsDialogRibbed::determineDirection(double orientation)
    {
        int angle = 0;
        if (orientation < 90 || qFuzzyCompare(orientation, 360))  angle = 0;
        else if (orientation < 180)  angle = 90;
        else if (orientation < 270)  angle = 180;
        else if (orientation < 360)  angle = 270;
        return angle;
    }
}